package com.x.mvp.crypto;

import android.util.Base64;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

public class RSAUtil {
    private static final String KEY_ALGORITHM = "RSA";

    private static final int MAX_ENCRYPT_BLOCK = 53;

    public static byte[] encryptByPublicKey(byte[] data, String publicKey)
            throws Exception {
        Key publicK = getPublicKey(publicKey);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM + "/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] cache;
        int i = 0;
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offSet, inputLen - offSet);
            }
            out.write(cache, 0, cache.length);
            i++;
            offSet = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    static public String decryptByPublicKey(byte[] cipherText, String publicKey) {
        byte[] sourceText = null;

        try {
            Key publicK = getPublicKey(publicKey);
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM + "/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, publicK);
            sourceText = cipher.doFinal(cipherText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new String(sourceText);

    }

    private static PublicKey getPublicKey(String publicKey) throws Exception {
        X509EncodedKeySpec spec =
                new X509EncodedKeySpec(Base64.decode(publicKey.getBytes(), Base64.DEFAULT));
        KeyFactory kf = KeyFactory.getInstance(KEY_ALGORITHM);
        return kf.generatePublic(spec);
    }
}